﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using BEELab.Data;
using System.Data;
using System.Data.SqlClient;
using System.Text;

namespace BEELab.Logic.ProgramManagement.StageManagement
{
    public static class AddRemoveFunction
    {
        /// <summary>
        /// Add new function to DB, relating it to ProgramID and StageID.
        /// </summary>
        /// <param name="InstanceName">Function Instance Name</param>
        /// <param name="ProgramID">Program ID</param>
        /// <param name="StageID">Stage ID</param>
        /// <param name="FunctionID">Function ID</param>
        /// <returns>Container ID that holds the function</returns>
        public static int AddFunction(string InstanceName, int ProgramID, int StageID, int FunctionID)
        {
            SqlCommand command = new SqlCommand();
            command.CommandText = "SELECT Name FROM Programs WHERE ID=@ID";
            command.Parameters.Add(new SqlParameter("@ID", FunctionID));
            string Type = DBHelper.ExecuteScalar(command);

            command = new SqlCommand();
            command.CommandText = "SELECT Type FROM Programs WHERE ID=@ID";
            command.Parameters.Add(new SqlParameter("@ID", ProgramID));
            string toType = DBHelper.ExecuteScalar(command);
            Boolean toFunction = toType.Equals("Function");

            int ContainerID = ContainerManagement.CreateContainer(StageID, Type, InstanceName, FunctionID);

            string prefix = "";
            if (InstanceName != null && InstanceName != "")
            {
                prefix = InstanceName + "_";
            }

            Dictionary<string, string> VariableNameDictionary = new Dictionary<string, string>();
            foreach (int id in ProgramManagement.VariableManagement.VariableManagement.ListByProgramID(FunctionID))
            {
                string name = VariableManagement.VariableManagement.GetNameByID(id);
                VariableNameDictionary.Add(name, prefix + name);
                ContainerManagement.AddElement(ContainerID, "Variable", ProgramManagement.VariableManagement.VariableManagement.ImportVariable(id, ProgramID, prefix), name);
            }

            Dictionary<string, string> NamesDictionary = ProgramManagement.StageManagement.StageManagement.ImportStageIntoStage(FunctionManagement.GetExecutionStageID(FunctionID), StageID, ContainerID, prefix, false, false, new Dictionary<int,int>());

            StringBuilder content;
            foreach (KeyValuePair<int, string> element in ContainerManagement.ListByContainerID(ContainerID))
            {
                if (element.Value != "Variable")
                {
                    content = new StringBuilder(BlockElements.GetContent(element.Key));

                    if (element.Value == "BlockElement")
                    {
                        if (BlockElements.GetType(element.Key) != "Code")
                        {
                            continue;
                        }
                    }

                    foreach (string key in VariableNameDictionary.Keys)
                    {
                        content.Replace(Properties.Settings.Default.VariablePrefix + key + Properties.Settings.Default.VariableSuffix, Properties.Settings.Default.VariablePrefix + VariableNameDictionary[key] + Properties.Settings.Default.VariableSuffix);
                        if (toFunction)
                            content.Replace(Properties.Settings.Default.VariableNamePrefix + key + Properties.Settings.Default.VariableNamePrefix, Properties.Settings.Default.VariableNamePrefix + VariableNameDictionary[key] + Properties.Settings.Default.VariableNameSuffix);
                        else
                            content.Replace(Properties.Settings.Default.VariableNamePrefix + key + Properties.Settings.Default.VariableNamePrefix, VariableNameDictionary[key]);
                    }

                    foreach (string key in NamesDictionary.Keys)
                    {
                        content.Replace(Properties.Settings.Default.BlockPrefix + key + Properties.Settings.Default.BlockSuffix, Properties.Settings.Default.BlockPrefix + NamesDictionary[key] + Properties.Settings.Default.BlockSuffix);
                        content.Replace(Properties.Settings.Default.BlockPrefix + key + Properties.Settings.Default.VariableSuffix, Properties.Settings.Default.BlockPrefix + NamesDictionary[key] + Properties.Settings.Default.VariableSuffix);
                        content.Replace(Properties.Settings.Default.PresentationPrefix + key + Properties.Settings.Default.PresentationSuffix, Properties.Settings.Default.PresentationPrefix + NamesDictionary[key] + Properties.Settings.Default.PresentationSuffix);
                    }

                    BlockElements.SetContent(element.Key, content.ToString());
                }
                else
                {
                    content = new StringBuilder(VariableManagement.VariableManagement.GetDefaultValue(element.Key));

                    foreach (string key in VariableNameDictionary.Keys)
                    {
                        content.Replace(Properties.Settings.Default.VariablePrefix + key + Properties.Settings.Default.VariableSuffix, Properties.Settings.Default.VariablePrefix + VariableNameDictionary[key] + Properties.Settings.Default.VariableSuffix);
                        if (toFunction)
                            content.Replace(Properties.Settings.Default.VariableNamePrefix + key + Properties.Settings.Default.VariableNamePrefix, Properties.Settings.Default.VariableNamePrefix + VariableNameDictionary[key] + Properties.Settings.Default.VariableNameSuffix);
                        else
                            content.Replace(Properties.Settings.Default.VariableNamePrefix + key + Properties.Settings.Default.VariableNamePrefix, VariableNameDictionary[key]);
                    }

                    foreach (string key in NamesDictionary.Keys)
                    {
                        content.Replace(Properties.Settings.Default.BlockPrefix + key + Properties.Settings.Default.BlockSuffix, Properties.Settings.Default.BlockPrefix + NamesDictionary[key] + Properties.Settings.Default.BlockSuffix);
                        content.Replace(Properties.Settings.Default.BlockPrefix + key + Properties.Settings.Default.VariableSuffix, Properties.Settings.Default.BlockPrefix + NamesDictionary[key] + Properties.Settings.Default.VariableSuffix);
                        content.Replace(Properties.Settings.Default.PresentationPrefix + key + Properties.Settings.Default.PresentationSuffix, Properties.Settings.Default.PresentationPrefix + NamesDictionary[key] + Properties.Settings.Default.PresentationSuffix);
                    }

                    VariableManagement.VariableManagement.SetDefaultValue(element.Key, content.ToString());
                }
            }

            return ContainerID;
        }

        public static Boolean RemoveFunction(int ContainerID)
        {
            return ContainerManagement.DeleteContainer(ContainerID);
        }

        public static Boolean RemoveFunction(int StageID, string InstanceName)
        {
            SqlCommand command = new SqlCommand();
            command.CommandText = "SELECT ContainerID FROM Containers WHERE StageID=@StageID AND Name=@Name";
            command.Parameters.Add(new SqlParameter("@StageID", StageID));
            command.Parameters.Add(new SqlParameter("@Name", InstanceName));
            int ContainerID = int.Parse(DBHelper.ExecuteScalar(command));

            return RemoveFunction(ContainerID);
        }
    }
}